#include <stdio.h>
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "esp_nimble_hci.h"
#include "nimble/nimble_port.h"
#include "nimble/nimble_port_freertos.h"
#include "host/ble_hs.h"
#include "host/util/util.h"
#include "host/ble_hs_pvcy.h"
#include "services/gap/ble_svc_gap.h"
#include "services/gatt/ble_svc_gatt.h"
#include "host/ble_sm.h"
#include "nvs.h"
#include "host/ble_uuid.h"

extern int ble_sm_init(void);

extern void ble_store_config_init(void);

uint8_t io_list[] = {GPIO_NUM_12, GPIO_NUM_13, GPIO_NUM_14, GPIO_NUM_21, GPIO_NUM_47}; // 定义 IO 口列表

static bool isBound = false; // 保存绑定的 MAC 地址

static const char *TAG = "Car_BLE_Framework";

static uint8_t ble_addr_type;

static ble_uuid128_t custom_service_uuid;

static ble_uuid128_t custom_characteristic_uuid;

static uint16_t car_chr_val_handle;

static int custom_write_callback(uint16_t conn_handle, uint16_t attr_handle,
                                 struct ble_gatt_access_ctxt *ctxt, void *arg);

/* GATT services table */
static const struct ble_gatt_svc_def gatt_services[] = {
    /* Heart rate service */
    {.type = BLE_GATT_SVC_TYPE_PRIMARY,
     .uuid = &custom_service_uuid.u,
     .characteristics =
         (struct ble_gatt_chr_def[]){
             {/* Heart rate characteristic */
              .uuid = &custom_characteristic_uuid.u,
              .access_cb = custom_write_callback,
              .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_INDICATE,
              .val_handle = &car_chr_val_handle},
             {
                 0, /* No more characteristics in this service. */
             }}},
    {
        0, /* No more services. */
    },
};

// 初使化IO中为输出模式
static void io_init(uint8_t pin)
{
    gpio_set_direction(pin, GPIO_MODE_OUTPUT); // 设置为输出模式
    gpio_set_level(pin, 0);                    // 设置初始电平为低电平
}

// 操作IO口输出高低电平
static void io_output_high_low(uint8_t pin, bool isHight)
{
    esp_err_t ec = gpio_set_level(pin, isHight ? 1 : 0);
    ESP_LOGI(TAG, "操作gpio:%d, %s,%s", pin, isHight ? "高电平" : "低电平", ec == ESP_OK ? "成功" : "失败");
}

static void pressKey(uint8_t pin, uint32_t delay_ms)
{
    io_output_high_low(pin, true);
    vTaskDelay(delay_ms / portTICK_PERIOD_MS);
    io_output_high_low(pin, false);
}

static int custom_write_callback(uint16_t conn_handle, uint16_t attr_handle,
                                 struct ble_gatt_access_ctxt *ctxt, void *arg)
{
    if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR)
    {
        struct ble_gap_conn_desc desc;
        int rc = ble_gap_conn_find(conn_handle, &desc);
        if (rc == 0)
        {
            if (desc.sec_state.bonded != 1)
            {
                ESP_LOGI(TAG, "未绑定设备，拒绝写入操作");
                return BLE_ATT_ERR_INSUFFICIENT_AUTHEN;
            }
            else
            {
                ESP_LOGI(TAG, "绑定设备，允许写入操作");
            }
            if (attr_handle == car_chr_val_handle)
            {
                /* Verify access buffer length */
                switch (ctxt->om->om_len)
                {
                case 1:
                {
                    uint8_t itx = ctxt->om->om_data[0];
                    if (itx < sizeof(io_list) / sizeof(io_list[0]))
                    {
                        ESP_LOGI(TAG, "GPIO_%d", io_list[itx]);
                        pressKey(io_list[itx], 300);
                    }
                    else
                    {
                        ESP_LOGE(TAG, "无效的 GPIO 口索引: %d", itx);
                        return BLE_ATT_ERR_VALUE_NOT_ALLOWED;
                    }
                }
                break;
                case 1 + 4:
                {
                    uint8_t itx = ctxt->om->om_data[0];

                    if (itx < sizeof(io_list) / sizeof(io_list[0]))
                    {
                        uint32_t delay = *((uint32_t*)ctxt->om->om_data + 1);
                        if (delay == 0)
                            delay = 300;
                        ESP_LOGI(TAG, "GPIO_%d, 延时: %ld ms", io_list[itx], delay);
                        pressKey(io_list[itx], delay);
                    }
                    else
                    {
                        ESP_LOGE(TAG, "无效的 GPIO 口索引: %d", itx);
                        return BLE_ATT_ERR_VALUE_NOT_ALLOWED;
                    }
                }
                break;
                }
            }
            else
            {
                ESP_LOGE(TAG, "无效的属性句柄: %d", attr_handle);
                return BLE_ATT_ERR_INVALID_HANDLE;
            }
        }
    }
    return 0; // 返回 0 表示成功
}

// 保存 MAC 地址到 NVS
static void save_bound_flag(bool bBound)
{
    nvs_handle_t nvs_handle;
    esp_err_t err = nvs_open("storage", NVS_READWRITE, &nvs_handle);
    if (err == ESP_OK)
    {
        nvs_set_i8(nvs_handle, "bound_flag", bBound ? true : false);
        nvs_commit(nvs_handle);
        nvs_close(nvs_handle);
    }
    else
    {
        ESP_LOGE(TAG, "无法打开 NVS 存储: %s", esp_err_to_name(err));
    }
}
// 从 NVS 加载 MAC 地址
static void load_boundflag_from_nvs()
{
    nvs_handle_t nvs_handle;
    esp_err_t err = nvs_open("storage", NVS_READONLY, &nvs_handle);
    if (err == ESP_OK)
    {
        int8_t _isBound;
        err = nvs_get_i8(nvs_handle, "bound_flag", &_isBound);

        isBound = _isBound ? true : false; // 设置为绑定状态

        nvs_close(nvs_handle);
        if (err == ESP_OK)
        {
            ESP_LOGI(TAG, "绑定状态: %s", isBound ? "true" : "false");
        }
        else
        {
            isBound = false; // 设置为默认值
        }
    }
    else
    {
        ESP_LOGW(TAG, "无法打开 NVS 存储: %s", esp_err_to_name(err));
        isBound = false; // 设置为默认值
    }
}
static int ble_gap_event_fun(struct ble_gap_event *event, void *arg);

#define BLE_GAP_URI_PREFIX_HTTPS 0x17

static uint8_t addr_val[6] = {0};

static uint8_t esp_uri[] = {BLE_GAP_URI_PREFIX_HTTPS, '/', '/', 'e', 's', 'p', 'r', 'e', 's', 's', 'i', 'f', '.', 'c', 'o', 'm'};

// 设置广播数据
static void start_advertising(void)
{
    if (ble_gap_adv_active())
    {
        ESP_LOGW(TAG, "广播已经启动，跳过重新启动");
        return;
    }
    /* Local variables */
    int rc = 0;
    const char *name;
    struct ble_hs_adv_fields adv_fields = {0};
    struct ble_hs_adv_fields rsp_fields = {0};
    struct ble_gap_adv_params adv_params = {0};

    /* Set advertising flags */
    adv_fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP;

    /* Set device name */
    name = ble_svc_gap_device_name();
    adv_fields.name = (uint8_t *)name;
    adv_fields.name_len = strlen(name);
    adv_fields.name_is_complete = 1;

    rc = ble_gap_adv_set_fields(&adv_fields);
    if (rc != 0)
    {
        ESP_LOGE(TAG, "设置广播数据失败, 错误代码: %d", rc);
    }

    /* Set device address */
    rsp_fields.device_addr = addr_val;
    rsp_fields.device_addr_type = ble_addr_type;
    rsp_fields.device_addr_is_present = 1;

    /* Set URI */
    rsp_fields.uri = esp_uri;
    rsp_fields.uri_len = sizeof(esp_uri);

    /* Set advertising interval */
    rsp_fields.adv_itvl = BLE_GAP_ADV_ITVL_MS(500);
    rsp_fields.adv_itvl_is_present = 1;

    /* Set scan response fields */
    rc = ble_gap_adv_rsp_set_fields(&rsp_fields);
    if (rc != 0)
    {
        ESP_LOGE(TAG, "failed to set scan response data, error code: %d", rc);
        return;
    }

    /* Set non-connetable and general discoverable mode to be a beacon */
    adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
    adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;

    /* Set advertising interval */
    adv_params.itvl_min = BLE_GAP_ADV_ITVL_MS(500);
    adv_params.itvl_max = BLE_GAP_ADV_ITVL_MS(510);

    /* Start advertising */
    rc = ble_gap_adv_start(ble_addr_type, NULL, BLE_HS_FOREVER, &adv_params,
                           ble_gap_event_fun, NULL);
    if (rc != 0)
    {
        ESP_LOGE(TAG, "failed to start advertising, error code: %d", rc);
        return;
    }
    ESP_LOGI(TAG, "advertising started!");
}

void printBondedDevices(void)
{
    ble_addr_t peer_id_addrs[MYNEWT_VAL(BLE_STORE_MAX_BONDS)];
    int num_peers;
    int rc;

    rc = ble_store_util_bonded_peers(
        peer_id_addrs, &num_peers,
        sizeof peer_id_addrs / sizeof peer_id_addrs[0]);

    if (rc == 0 && num_peers > 0)
    {
        for (int i = 0; i < num_peers; i++)
        {
            ESP_LOGI(TAG, "配对设备地址: %02X:%02X:%02X:%02X:%02X:%02X",
                     peer_id_addrs[i].val[5], peer_id_addrs[i].val[4], peer_id_addrs[i].val[3],
                     peer_id_addrs[i].val[2], peer_id_addrs[i].val[1], peer_id_addrs[i].val[0]);
        }
    }
}

bool is_device_bonded(uint16_t conn_handle)
{
    printBondedDevices();

    struct ble_gap_conn_desc desc;
    int rc;

    // 获取连接描述符
    rc = ble_gap_conn_find(conn_handle, &desc);
    if (rc != 0)
    {
        ESP_LOGE(TAG, "无法找到连接句柄: %d", conn_handle);
        return false;
    }

    // 构建安全存储查询密钥
    struct ble_store_key_sec key_sec;
    memset(&key_sec, 0, sizeof(key_sec));
    memcpy(key_sec.peer_addr.val, desc.peer_id_addr.val, 6);
    key_sec.peer_addr.type = desc.peer_id_addr.type;

    // 打印所有已配对设备信息
    ESP_LOGI(TAG, "本地身份地址: %02X:%02X:%02X:%02X:%02X:%02X, 类型: %d",
             desc.our_id_addr.val[5], desc.our_id_addr.val[4], desc.our_id_addr.val[3],
             desc.our_id_addr.val[2], desc.our_id_addr.val[1], desc.our_id_addr.val[0],
             desc.our_id_addr.type);

    ESP_LOGI(TAG, "对端身份地址: %02X:%02X:%02X:%02X:%02X:%02X, 类型: %d",
             desc.peer_id_addr.val[5], desc.peer_id_addr.val[4], desc.peer_id_addr.val[3],
             desc.peer_id_addr.val[2], desc.peer_id_addr.val[1], desc.peer_id_addr.val[0],
             desc.peer_id_addr.type);

    ESP_LOGI(TAG, "本地 OTA 地址: %02X:%02X:%02X:%02X:%02X:%02X, 类型: %d",
             desc.our_ota_addr.val[5], desc.our_ota_addr.val[4], desc.our_ota_addr.val[3],
             desc.our_ota_addr.val[2], desc.our_ota_addr.val[1], desc.our_ota_addr.val[0],
             desc.our_ota_addr.type);

    ESP_LOGI(TAG, "对端 OTA 地址: %02X:%02X:%02X:%02X:%02X:%02X, 类型: %d",
             desc.peer_ota_addr.val[5], desc.peer_ota_addr.val[4], desc.peer_ota_addr.val[3],
             desc.peer_ota_addr.val[2], desc.peer_ota_addr.val[1], desc.peer_ota_addr.val[0],
             desc.peer_ota_addr.type);
    // 查询安全存储
    struct ble_store_value_sec sec_value;
    rc = ble_store_read(BLE_STORE_OBJ_TYPE_PEER_SEC, (const union ble_store_key *)&key_sec, (union ble_store_value *)&sec_value);
    if (rc == 0)
    {
        ESP_LOGI(TAG, "设备已配对");
        return true; // 已配对
    }
    else if (rc == BLE_HS_ENOENT)
    {
        ESP_LOGI(TAG, "设备未配对");
        return false; // 未找到配对记录
    }
    else
    {
        ESP_LOGE(TAG, "读取安全存储失败，错误代码: %d", rc);
        return false;
    }
}
static int ble_gap_event_fun(struct ble_gap_event *event, void *arg)
{
    int rc = 0;

    switch (event->type)
    {

    case BLE_GAP_EVENT_PARING_COMPLETE:
    {
        if (event->pairing_complete.status == 0)
        {
            // 如果是第一次配对，保存绑定状态
            if (!isBound)
            {
                save_bound_flag(true);
                isBound = true; // 设置为已绑定状态
                ESP_LOGI(TAG, "配对成功");
                printBondedDevices(); // 打印所有已配对设备信息
            }
        }
        else
        {
            ESP_LOGE(TAG, "配对失败，错误代码: %d", event->pairing_complete.status);
        }
    }
    break;
    case BLE_GAP_EVENT_REPEAT_PAIRING:
    {
        // 获取连接设备的 MAC 地址
        struct ble_gap_conn_desc desc;
        rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
        if (rc != 0)
        {
            ESP_LOGE(TAG, "failed to find connection, error code %d", rc);
            return rc;
        }
        ble_store_util_delete_peer(&desc.peer_id_addr);

        /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
         * continue with pairing operation */
        ESP_LOGI(TAG, "repairing...");
        return BLE_GAP_REPEAT_PAIRING_RETRY;
    }
    break;
    case BLE_GAP_EVENT_CONNECT:
        if (event->connect.status == 0)
        {
            ESP_LOGI(TAG, "设备已连接");
            // 获取连接设备的 MAC 地址
            struct ble_gap_conn_desc desc;
            rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
            if (rc == 0)
            {
                ESP_LOGI(TAG, "摘取设备信息");

                ESP_LOGI(TAG, "对端身份地址: %02X:%02X:%02X:%02X:%02X:%02X, 类型: %d",
                         desc.peer_id_addr.val[5], desc.peer_id_addr.val[4], desc.peer_id_addr.val[3],
                         desc.peer_id_addr.val[2], desc.peer_id_addr.val[1], desc.peer_id_addr.val[0],
                         desc.peer_id_addr.type);

                // 判断设备是否已经配对
                if (isBound)
                {
                    ESP_LOGI(TAG, "判断设备是否已经配对：%d", desc.sec_state.bonded);
                    if (is_device_bonded(event->connect.conn_handle))
                    {
                        ESP_LOGI(TAG, "已绑定设备，允许连接");
                        ESP_LOGI(TAG, "连接设备信息: 加密=%d, 验证=%d, 绑定=%d",
                                 desc.sec_state.encrypted,
                                 desc.sec_state.authenticated,
                                 desc.sec_state.bonded);
                        if (!desc.sec_state.encrypted || !desc.sec_state.bonded)
                        {
                            rc = ble_gap_security_initiate(event->connect.conn_handle);
                            if (rc != 0)
                            {
                                ESP_LOGE(TAG, "安全连接失败，错误代码: %d", rc);
                                ble_gap_terminate(event->connect.conn_handle, BLE_ERR_REM_USER_CONN_TERM);
                                return rc;
                            }
                        }
                        else
                        {
                            ESP_LOGI(TAG, "设备已加密且绑定，无需启动安全连接");
                        }
                    }
                    else
                    {
                        ESP_LOGI(TAG, "已有设备配对，但此设备不是绑定设备，断开连接");
                        ble_gap_terminate(event->connect.conn_handle, BLE_ERR_REM_USER_CONN_TERM);
                        return rc;
                    }
                }
                else
                {
                    ESP_LOGI(TAG, "开始配对设备");
                    rc = ble_gap_security_initiate(event->connect.conn_handle);
                    if (rc != 0)
                    {
                        ESP_LOGE(TAG, "安全连接失败，错误代码: %d", rc);
                        ble_gap_terminate(event->connect.conn_handle, BLE_ERR_REM_USER_CONN_TERM);
                        return rc;
                    }
                }
            }
            else
            {
                ESP_LOGE(TAG, "获取连接描述失败，错误代码: %d", rc);
                return rc;
            }
        }
        else
        {
            ESP_LOGE(TAG, "连接失败，重新开始广播");
            start_advertising();
        }
        break;
    case BLE_GAP_EVENT_DISCONNECT:
        ESP_LOGI(TAG, "设备已断开连接，重新开始广播");
        start_advertising();
        break;

    case BLE_GAP_EVENT_ADV_COMPLETE:
        ESP_LOGI(TAG, "广播完成，重新开始广播");
        start_advertising();
        break;

    case BLE_GAP_EVENT_PASSKEY_ACTION:
        struct ble_sm_io pkey = {0};
        pkey.action = event->passkey.params.action;
        pkey.passkey = 123456;
        if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP)
        {
            pkey.numcmp_accept = 1; // 自动接受数字比较
        }
        int rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
        if (rc != 0)
        {
            ESP_LOGE(TAG, "注入配对信息失败，错误代码: %d", rc);
        }
        break;

    case BLE_GAP_EVENT_ENC_CHANGE:
        if (event->enc_change.status == 0)
        {
            ESP_LOGI(TAG, "加密成功，设备已验证");
        }
        else
        {
            ESP_LOGE(TAG, "加密失败，断开连接");
            ble_gap_terminate(event->connect.conn_handle, BLE_ERR_REM_USER_CONN_TERM);
        }
        break;

    default:
        break;
    }
    return 0;
}

// 初始化 NimBLE 堆栈
#define DEVICE_NAME "MyCar" // Define the device name

static void ble_app_on_sync(void)
{
    int rc = 0;

    // 启用隐私功能
    rc = ble_hs_pvcy_set_resolve_enabled(1); // 参数 1 表示启用 RPA（Resolvable Private Address）
    if (rc != 0)
    {
        ESP_LOGE(TAG, "启用隐私功能失败: %d", rc);
        return;
    }

    rc = ble_hs_id_infer_auto(0, &ble_addr_type);
    if (rc != 0)
    {
        ESP_LOGE(TAG, "无法设置 BLE 地址类型: %d", rc);
        return;
    }

    ble_hs_id_copy_addr(ble_addr_type, addr_val, NULL);
    ESP_LOGI(TAG, "设备地址: %02X:%02X:%02X:%02X:%02X:%02X",
             addr_val[5], addr_val[4], addr_val[3],
             addr_val[2], addr_val[1], addr_val[0]);

    ble_svc_gap_init();
    ble_svc_gatt_init();
    /* Set GAP device name */
    rc = ble_svc_gap_device_name_set(DEVICE_NAME);
    ble_gattc_init(); // Initialize GATT client

    // 注册 GATT 服务
    rc = ble_gatts_count_cfg(gatt_services);
    if (rc != 0)
    {
        ESP_LOGE(TAG, "GATT 服务计数失败: %d", rc);
        return;
    }

    rc = ble_gatts_add_svcs(gatt_services);
    if (rc != 0)
    {
        ESP_LOGE(TAG, "添加 GATT 服务失败: %d", rc);
        return;
    }

    ble_gatts_start(); // Start GATT server

    start_advertising();
}

// BLE 主任务
void ble_host_task(void *param)
{
    nimble_port_run(); // 运行 NimBLE 堆栈
    nimble_port_freertos_deinit();
}

// Declare a task handle for long press task
TaskHandle_t task_handle = NULL;

// Task to handle long press detection
void long_press_task(void *arg)
{
    while (1)
    {
        ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // Wait for notification

        // 长按检测
        uint32_t start_time = esp_timer_get_time(); // 获取当前时间
        while (gpio_get_level(GPIO_NUM_0) == 0)     // 检测 GPIO 0 是否为低电平
        {
            vTaskDelay(10 / portTICK_PERIOD_MS);             // 延时 10 毫秒
            if (esp_timer_get_time() - start_time > 3000000) // 如果按下时间超过 3 秒
            {
                break; // 跳出循环
            }
        }
        if (gpio_get_level(GPIO_NUM_0) == 1) // 如果 GPIO 0 为高电平
        {
            continue; // 返回，表示没有长按
        }

        // 清除绑定信息
        ESP_LOGI(TAG, "长按 GPIO 0，清除绑定信息");
        nvs_handle_t _nvs_handle;
        esp_err_t err = nvs_open("storage", NVS_READWRITE, &_nvs_handle);
        if (err == ESP_OK)
        {

            ESP_LOGI(TAG, "清除所有配对信息");
            int rc;
            rc = ble_store_clear();
            if (rc != 0)
            {
                ESP_LOGE(TAG, "清除配对信息失败，错误代码: %d", rc);
            }

            nvs_erase_key(_nvs_handle, "bound_flag");
            nvs_commit(_nvs_handle);
            nvs_close(_nvs_handle);
            isBound = false;
            ESP_LOGI(TAG, "绑定状态已重置为 false");
            // 重启ESP
            esp_restart();
        }
    }
}

static void gpio_isr_handler(void *arg)
{
    // Post an event or set a flag to handle the long press in a task
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    xTaskNotifyFromISR(task_handle, 0, eNoAction, &xHigherPriorityTaskWoken);

    // Yield to a higher-priority task if needed
    if (xHigherPriorityTaskWoken == pdTRUE)
    {
        portYIELD_FROM_ISR();
    }
}

void initUUID()
{
    ble_uuid_from_str((ble_uuid_any_t *)&custom_service_uuid, "91486214-AB7F-E39C-5A68-C1F2D4A9B73E");
    ble_uuid_from_str((ble_uuid_any_t *)&custom_characteristic_uuid, "3EB7A9D4-F2C1-685A-9CE3-7FAB14624891");
}

void app_main(void)
{
    // 打开调用日志
    // esp_log_level_set("*", ESP_LOG_DEBUG);

    initUUID();
    // 初始化 NVS
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);
    // 从 NVS 加载绑定的标志
    load_boundflag_from_nvs();
    // Configure GPIO 0 as input with pull-up resistor
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << GPIO_NUM_0),
        .mode = GPIO_MODE_INPUT,
        .pull_up_en = GPIO_PULLUP_ENABLE,
        .intr_type = GPIO_INTR_NEGEDGE // Interrupt on falling edge
    };
    xTaskCreate(long_press_task, "LongPressTask", 4096, NULL, 10, &task_handle);
    gpio_config(&io_conf);
    // GPIO_NUM_0 中断处理
    gpio_install_isr_service(0); // 安装 GPIO 中断服务
    // Function to handle GPIO interrupt
    gpio_isr_handler_add(GPIO_NUM_0, gpio_isr_handler, NULL);

    // 初始化其他 GPIO 口
    for (size_t i = 0; i < sizeof(io_list) / sizeof(io_list[0]); i++)
    {
        io_init(io_list[i]); // 初始化 GPIO 口
    }

    // 配置安全参数
    ble_hs_cfg.sm_bonding = 1;                      // 启用绑定
    ble_hs_cfg.sm_mitm = 1;                         // 需要 MITM（中间人攻击保护）
    ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_DISP_ONLY; // 设置为仅显示能力
    ble_hs_cfg.sm_sc = 1;                           // 启用安全连接
    ble_hs_cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID | BLE_SM_PAIR_KEY_DIST_SIGN;
    ble_hs_cfg.sm_their_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID | BLE_SM_PAIR_KEY_DIST_SIGN; // ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK
    ble_hs_cfg.sm_sc_only = 0;
    ble_hs_cfg.sm_keypress = 1;      // 启用按键输入
    ble_hs_cfg.sm_oob_data_flag = 0; // 禁用 OOB 数据
    ble_hs_cfg.sync_cb = ble_app_on_sync;

    // 初始化存储
    ble_store_config_init();
    ble_sm_init();
    nimble_port_init();

    // 启动 NimBLE 主任务
    nimble_port_freertos_init(ble_host_task);
}